import { cloneDeep } from "lodash";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { App } from "vue";
import router, { asyncRoutes } from "../router/index";
import { useUserStore } from "../store/user";
import { getToken } from "../utils/auth";
import getPageTitle from "../utils/getPageTitle";

const whiteList = ["/login"];

export default function checkPermission(app: App) {
  router.beforeEach((to) => {
    NProgress.start();
    document.title = getPageTitle(to.meta.title);
    const hasToken = getToken();
    if (hasToken) {
      return handleHasToken(to);
    } else {
      return handleNoToken(to);
    }
  });

  app.directive("has", checkButtonPermission);

  router.afterEach(() => {
    NProgress.done();
  });
}

async function handleHasToken(to) {
  const { getInfo } = useUserStore();
  const { roles, menuList } = await getInfo();
  handleRoutes(roles, menuList);
  if (!router.hasRoute(to.name)) {
    // 针对直接通过路径刷新访问的情况
    return to.path;
  }
  if (to.path === "/login") {
    return "/";
  } else {
    return true;
  }
}

function handleNoToken(to) {
  if (!whiteList.includes(to.path)) {
    return "/login";
  }
  return true;
}

async function handleRoutes(roles, menuList) {
  if (roles.includes("超级管理员")) {
    asyncRoutes.forEach((route) => {
      router.addRoute(route);
    });
    return;
  }
  let routes = cloneDeep(asyncRoutes);
  const menus = menuList ? menuList.split(",") : [];
  routes = setRouteShow(routes, menus);
  routes.forEach((route) => {
    router.addRoute(route);
  });
}

function setRouteShow(routes, menus) {
  const newRoutes = [];
  routes.forEach((route) => {
    if (route.children && route.children.length > 0) {
      route.children = setRouteShow(route.children, menus);
      if (route.children.length > 0) {
        newRoutes.push(route);
      }
    } else {
      if (menus.includes(route.name)) {
        newRoutes.push(route);
      }
    }
  });
  return newRoutes;
}

function checkButtonPermission(el, { value }) {
  const { permissionIds, roles } = useUserStore();
  if (roles.includes("超级管理员")) return;
  if (!permissionIds.includes(value)) {
    el.remove();
  }
}
